<template>
  <div class="app-container">
    <div class="topSearch">
      <el-row>
        <el-input
          v-model="searchCriteria.sku"
          clearable
          maxlength="50"
          placeholder="Name"
        />
        <el-input
          v-model="searchCriteria.name"
          maxlength="50"
          clearable
          placeholder="Sku"
        />
        <el-button type="primary" @click="searchData()">Search</el-button>
      </el-row>
      <el-row>
        <el-button
          type="primary"
          @click="showDialog('add')"
        >Add Design</el-button>
        <el-button type="primary" @click="toSelect">Move To Group</el-button>
      </el-row>
    </div>
    <div class="content">
      <div style="width:255px !important;">
        <sticky :z-index="8" :sticky-top="80">
          <div
            id="groupTree"
            class="groupTree"
            :style="{ height: height + 'px' }"
          >
            <div>
              <p>
                Design Group
                <el-button
                  type="text"
                  style="float:right"
                  @click="showAddGroup('add')"
                >ADD</el-button>
              </p>
              <el-tree
                ref="groupTree"
                :data="allGroupOptions"
                :highlight-current="true"
                :props="defaultProps"
              >
                <span
                  slot-scope="{ node, data }"
                  class="custom-tree-node"
                  @click="groupFilter(data.id)"
                >
                  <span class="groupName" :gId="node.data.id">{{
                    node.label
                  }}</span>
                  <i
                    v-if="node.data.id !== 0"
                    v-preventReClick
                    :gId="node.data.id"
                    class="el-icon-delete"
                    @click.stop="deleteGroup(node.data.id)"
                  />
                </span>
              </el-tree>
            </div>
          </div>
        </sticky>
      </div>
      <div class="tableBox" :class="{ open: sidebar }">
        <el-table
          ref="dragTable"
          v-loading="loading"
          :data="tableData"
          @selection-change="handleSelectionChange"
          @cell-click="handleCellClick"
        >
          <el-table-column type="expand">
            <template slot-scope="scope">
              <el-row v-if="scope.row.variants.length" :gutter="20">
                <el-col
                  v-for="item in scope.row.variants"
                  :key="item.id"
                  class="productItem"
                  :span="8"
                >
                  <el-image
                    class="productImg"
                    :src="imgPrefix + item.thumbnailUri"
                    @click="toProview(imgPrefix + item.thumbnailUri)"
                  />
                  <p><span>Sku: </span>{{ item.variantSku }}</p>
                </el-col>
              </el-row>
              <p v-else style="text-align:center;color:#848484">No Products</p>
            </template>
          </el-table-column>
          <el-table-column type="selection" width="55" />
          <el-table-column label="Image" width="100">
            <template slot-scope="scope">
              <el-image
                class="productImg"
                lazy
                :src="imgPrefix + scope.row.material.thumbnailUri + imgSuffix"
                @click="toProview(imgPrefix + scope.row.material.thumbnailUri)"
              >
                <div slot="placeholder" class="image-slot">
                  <i class="el-icon-loading" />
                </div>
              </el-image>
            </template>
          </el-table-column>
          <el-table-column prop="material.sku" label="Name" />
          <el-table-column label="Sku">
            <template slot-scope="scope">
              <el-tag
                v-for="item in scope.row.variants"
                :key="item.id"
                style="margin-right:5px;"
              >{{ item.variantSku }}</el-tag>
            </template>
          </el-table-column>
          <el-table-column label="Group" width="130">
            <template slot-scope="scope">
              {{
                scope.row.material.materialGroupId === 0
                  ? 'no'
                  : groupMap[scope.row.material.materialGroupId]
              }}
            </template>
          </el-table-column>
          <el-table-column fixed="right" label="Operation" width="130">
            <template slot-scope="scope">
              <div>
                <el-button
                  type="text"
                  @click.stop="
                    downloadUrl(imgPrefix + scope.row.material.zipUri)
                  "
                >DownLoad</el-button>
              </div>
              <div>
                <el-button
                  type="text"
                  @click.stop="showDialog('edit', scope.row.material.id)"
                >Edit</el-button>
                <el-button
                  type="text"
                  @click.stop="deleteItem(scope.row.material.id)"
                >Delete</el-button>
              </div>
            </template>
          </el-table-column>
        </el-table>
        <el-pagination
          v-if="tableData.length"
          id="btmPagination"
          :class="{ open: sidebar }"
          :current-page="currentPage"
          :page-sizes="[10, 30, 50, 100, 200]"
          :page-size="pageSize"
          layout="total, sizes, prev, pager, next, jumper"
          :total="total"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        />
      </div>
    </div>

    <!-- 新增/编辑素材弹窗 -->
    <el-dialog
      v-if="dialogFormVisible"
      :title="dialogTitle"
      :visible.sync="dialogFormVisible"
      width="750px"
    >
      <div v-loading="editLoading">
        <el-form
          ref="ruleForm"
          :model="material"
          :rules="rules"
          :label-width="formLabelWidth"
        >
          <div class="title">
            Basic Information
          </div>
          <el-row type="flex" justify="space-between">
            <el-form-item prop="sku" label="Design Name">
              <el-input v-model="material.sku" />
            </el-form-item>
            <el-form-item prop="materialGroupId" label="Design Group">
              <el-select
                v-model="material.materialGroupId"
                placeholder="design group"
              >
                <el-option
                  v-for="item in groupOptions"
                  :key="item.id"
                  :label="item.name"
                  :value="item.id"
                />
              </el-select>
            </el-form-item>
          </el-row>
          <el-row type="flex" justify="space-between">
            <el-form-item
              prop="thumbnailUri"
              label="Design Image"
              class="thumbnailUri"
            >
              <upload-image
                :img-url="material.thumbnailUri"
                @getImg="mainImg"
              />
            </el-form-item>
            <el-form-item prop="zipUri" label="Design File">
              <upload-zip :file-url="material.zipUri" @succ="onSucc" />
            </el-form-item>
          </el-row>

          <div class="title">
            Product Information
            <el-button type="text" @click="addVariant">Add Product</el-button>
          </div>
          <div
            v-for="(item, index) in variants"
            :key="index"
            class="variantItem"
          >
            <div class="leftArea">
              <el-row type="flex" justify="space-between">
                <el-form-item
                  ref="imgItem"
                  :label-width="formLabelWidth"
                  label="Product Image"
                  style="width: 337px;"
                  required
                >
                  <upload-image
                    :img-url="item.thumbnailUri"
                    :n-index="index"
                    @getImg="variantImg"
                  />
                </el-form-item>
                <el-form-item
                  :label-width="formLabelWidth"
                  label="Product Sku"
                  required
                >
                  <el-input
                    v-model="item.variantSku"
                    clearable
                    @blur="variantSkuBlur(item, index)"
                  />
                </el-form-item>
              </el-row>
            </div>
            <div class="rightArea">
              <el-button
                type="danger"
                icon="el-icon-delete"
                circle
                @click="deleteVariant(index)"
              />
            </div>
          </div>
          <div v-if="variants.length === 0" class="tip">
            <!-- 暂无变种信息 -->
            No variant information available!
          </div>
        </el-form>
        <div slot="footer" class="dialog-footer">
          <el-button @click="dialogFormVisible = false">Cancel</el-button>
          <el-button
            v-preventReClick
            type="primary"
            @click="submitData('ruleForm')"
          >Confirm</el-button>
        </div>
      </div>
    </el-dialog>

    <!-- 编辑/更换分组 -->
    <el-dialog
      v-if="selectGroupVisible"
      title="Change Design Group"
      :visible.sync="selectGroupVisible"
      width="400px"
    >
      <el-form label-width="110px">
        <el-form-item label="Select Group">
          <el-select
            v-model="materialGroupId"
            placeholder="Please select group"
          >
            <el-option
              v-for="item in groupOptions"
              :key="item.id"
              :label="item.name"
              :value="item.id"
            />
          </el-select>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="selectGroupVisible = false">Cancel</el-button>
        <el-button
          v-preventReClick
          :disabled="!materialGroupId"
          type="primary"
          @click="moveGroup"
        >Confirm</el-button>
      </div>
    </el-dialog>

    <!-- 添加分组 -->
    <el-dialog
      title="Add Design Group"
      :visible.sync="addGroupVisible"
      width="400px"
    >
      <el-form label-width="110px">
        <el-form-item label="Group Name">
          <el-input v-model="groupName" />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="addGroupVisible = false">Cancel</el-button>
        <el-button
          v-preventReClick
          :disabled="!groupName"
          type="primary"
          @click="addGroup"
        >Confirm</el-button>
      </div>
    </el-dialog>
    <!-- 图片预览 -->
    <proview-img v-if="proviewUrl" :src="proviewUrl" @close="closeProview" />
  </div>
</template>

<script>
import {
  materialPage,
  materialAdd,
  materialEdit,
  materialRead,
  materialDelete,
  materialGroupList,
  materialSku,
  materialVariantSku,
  materialMove,
  materialGroupAdd,
  materialGroupDelete
} from '@/api/material';
import Sticky from '@/components/Sticky';
import UploadImage from '@/components/Upload/uploadImg';
import UploadZip from '@/components/Upload/uploadZip';
import ProviewImg from '@/components/Proview/proviewImg';
import { postResult } from '@/utils/dataFormat';
import { downloadUrl } from '@/utils/downLoad';
import { checkHalf, validateField } from '@/utils/validate';
export default {
  components: {
    UploadImage,
    UploadZip,
    ProviewImg,
    Sticky
  },
  data() {
    return {
      height: 420,
      defaultProps: {
        children: 'children',
        label: 'name'
      },
      proviewUrl: '',
      searchCriteria: {},
      tableData: [],
      cloneData: [],
      multipleSelection: [],
      loading: false,
      groupMap: {},
      currentPage: 1,
      pageSize: 10,
      total: 0,
      dialogFormVisible: false,
      editLoading: false,
      dialogType: 'add',
      material: {},
      variants: [],
      rules: {
        name: [
          {
            validator: (rule, value, callback) =>
              validateField(rule, value, callback, 300),
            required: true
          }
        ],
        sku: [
          { validator: checkHalf, required: true },
          { max: 300, message: 'please enter 1 to 300 characters' }
        ],
        materialGroupId: [
          {
            required: true,
            message: 'Please select the design group',
            trigger: 'change'
          }
        ],
        thumbnailUri: [
          {
            required: true,
            message: 'Please upload pictures',
            trigger: 'change'
          }
        ],
        zipUri: [
          {
            required: true,
            message: 'Please upload the design file',
            trigger: 'change'
          }
        ]
      },
      groupOptions: [],
      allGroupOptions: [],
      formLabelWidth: '140px',
      selectGroupVisible: false,
      materialGroupId: null,
      addGroupVisible: false,
      groupName: '',
      eleDrag: null,
      eleDragIndex: null,
      isPass: false,
      isSkuPass: false
    };
  },
  computed: {
    dialogTitle: function() {
      return this.dialogType === 'add'
        ? 'New design information'
        : this.dialogType === 'edit'
          ? 'Edit design information'
          : '';
    },
    sidebar() {
      return this.$store.state.app.sidebar.opened;
    }
  },
  mounted() {
    this.groupTreeHeight();
    window.addEventListener('resize', this.groupTreeHeight);
    this.materialGroupList();
    this.init();
  },
  beforeDestroy() {
    window.removeEventListener('resize', this.groupTreeHeight);
  },
  methods: {
    groupTreeHeight() {
      const clientHeight = document.documentElement.clientHeight;
      const eleTop = document.getElementById('groupTree').offsetTop;
      this.height = clientHeight - eleTop;
    },
    init() {
      this.loading = true;
      const data = this.searchCriteria;
      data.pageSize = this.pageSize;
      data.pageNo = this.currentPage;
      materialPage({
        ...this.searchCriteria,
        pageSize: this.pageSize,
        pageNo: this.currentPage
      }).then((res) => {
        this.tableData = res.data.data;
        this.cloneData = JSON.parse(JSON.stringify(res.data.data));
        this.total = res.data.totalCount;
        this.loading = false;
        this.$nextTick(() => {
          this.setDrop();
        });
      });
    },
    searchData() {
      this.currentPage = 1;
      this.init();
    },
    materialGroupList() {
      // 素材分组
      materialGroupList().then((res) => {
        const obj = {};
        res.data.forEach((item) => {
          obj[item.id] = item.name;
        });
        this.groupMap = obj;
        this.groupOptions = res.data;
        const data = JSON.parse(JSON.stringify(res.data));
        data.unshift({ id: 0, name: 'All' });
        this.allGroupOptions = data;
      });
    },
    toSelect() {
      // 选择分组弹窗
      if (this.multipleSelection.length === 0) {
        return this.$message.warning('Please select at least one');
      }
      this.selectGroupVisible = true;
    },
    setDrop() {
      // 设置table中tr可拖拽，分组列表监听拖拽事件
      const elTr = this.$refs.dragTable.$el.querySelectorAll(
        '.el-table__body-wrapper > table > tbody tr'
      );
      for (let i = 0; i < elTr.length; i++) {
        elTr[i].setAttribute('draggable', true);
        elTr[i].onselectstart = function() {
          return false;
        };
        elTr[i].ondragstart = (ev) => {
          if (ev.target.tagName === 'IMG') {
            this.eleDrag = ev.target.closest('tr.el-table__row');
          } else if (ev.target.tagName === 'TR') {
            this.eleDrag = ev.target;
          }
          this.eleDragIndex = this.eleDrag.rowIndex;
          return true;
        };
        elTr[i].ondragend = (ev) => {
          ev.dataTransfer.clearData('text');
          this.eleDrag = null;
          this.eleDragIndex = null;
          return false;
        };
      }
      const groupTree = this.$refs.groupTree.$el.querySelectorAll(
        '.el-tree-node'
      );
      for (let i = 0; i < groupTree.length; i++) {
        groupTree[i].ondragover = function(ev) {
          ev.preventDefault();
          return true;
        };
        groupTree[i].ondragenter = function(ev) {
          return true;
        };
        groupTree[i].ondragleave = function(ev) {
          return true;
        };
        groupTree[i].ondrop = (ev) => {
          if (this.eleDrag) {
            const materialGroupId = ev.toElement.getAttribute('gid');
            if (ev.toElement.getAttribute('gid')) {
              const materialId = this.tableData[this.eleDragIndex].id;
              materialMove({
                materialGroupId: materialGroupId,
                materialIds: [materialId]
              }).then((res) => {
                postResult(res, this.$message, this.init);
                if (res.code === 200) {
                  this.selectGroupVisible = false;
                }
              });
            }
          }
          return false;
        };
      }
    },
    moveGroup() {
      const ids = this.multipleSelection.map((item) => {
        return item.id;
      });
      materialMove({
        materialGroupId: this.materialGroupId,
        materialIds: ids
      }).then((res) => {
        postResult(res, this.$message, this.init);
        if (res.code === 200) {
          this.selectGroupVisible = false;
        }
      });
    },
    showAddGroup() {
      this.groupName = '';
      this.addGroupVisible = true;
    },
    addGroup() {
      materialGroupAdd({
        isLeaf: 0,
        name: this.groupName,
        parentId: 0
      }).then((res) => {
        postResult(res, this.$message, this.materialGroupList);
        if (res.code === 200) {
          this.addGroupVisible = false;
        }
      });
    },
    deleteGroup(id) {
      this.$confirm(
        'This action will permanently delete the group and whether to continue?',
        'Hint',
        {
          confirmButtonText: 'Yes',
          cancelButtonText: 'No',
          type: 'warning'
        }
      )
        .then(() => {
          materialGroupDelete([id]).then((res) => {
            postResult(res, this.$message, this.materialGroupList);
          });
        })
        .catch(() => {
          return false;
        });
    },
    groupFilter(id) {
      this.currentPage = 1;
      this.searchCriteria.materialGroupId = id;
      this.init();
    },
    handleSelectionChange(val) {
      this.multipleSelection = val;
    },
    handleCellClick(row, cell) {
      if (cell.label === 'Sku') {
        this.$refs.dragTable.toggleRowExpansion(row);
      }
    },
    mainImg(arr) {
      this.material.thumbnailUri = arr[0];
      this.$refs.ruleForm.clearValidate('thumbnailUri');
      this.rules['thumbnailUri'] = [];
    },
    variantImg(arr) {
      this.variants[arr[1]].thumbnailUri = arr[0];
    },
    onSucc(uri) {
      this.material.zipUri = uri;
      this.$refs.ruleForm.clearValidate('zipUri');
      this.rules['zipUri'] = [];
    },
    downloadUrl(url) {
      downloadUrl(url);
    },
    showDialog(type, id) {
      this.rules['zipUri'] = [
        {
          required: true,
          message: 'Please upload the design file',
          trigger: 'change'
        }
      ];
      this.rules['thumbnailUri'] = [
        { required: true, message: 'Please upload pictures', trigger: 'change' }
      ];
      this.isSkuPass = false;
      this.isPass = false;
      if (type === 'add') {
        // 新增
        this.editLoading = false;
        this.dialogType = 'add';
        this.material = {};
        this.variants = [];
        this.$nextTick(() => {
          this.dialogFormVisible = true;
        });
      } else if (type === 'edit') {
        // 编辑
        this.editLoading = true;
        this.dialogType = 'edit';
        materialRead(id)
          .then((res) => {
            this.editLoading = false;
            if (res.code === 200) {
              this.material = res.data['material'];
              this.variants = res.data['variants'];
              this.$nextTick(() => {
                this.dialogFormVisible = true;
              });
            } else {
              this.dialogFormVisible = false;
            }
          })
          .catch(() => {
            this.editLoading = false;
          });
      }
    },
    addVariant() {
      // 添加变种信息
      this.variants.push({
        variantSku: this.material.sku || ''
      });
    },
    deleteVariant(index) {
      this.variants.splice(index, 1);
    },
    skuBlur(item) {
      if (item) {
        this.checkSku(item);
      }
    },
    variantSkuBlur(item, index) {
      if (item.variantSku) {
        this.checkVariantSku(item, index);
      }
    },
    checkSku(item) {
      materialSku({
        id: this.material.id ? this.material.id : -1,
        sku: this.material.sku
      }).then((res) => {
        if (res.code !== 200) {
          // this.material.sku = ''
          this.$set(this.material, 'sku', '');
          this.isSkuPass = true;
        } else {
          this.isSkuPass = false;
        }
      });
    },
    checkVariantSku(item, index) {
      materialVariantSku({
        variantId: item.id ? item.id : -1,
        sku: item.variantSku
      }).then((res) => {
        if (res.code !== 200) {
          this.variants[index].variantSku = '';
          this.isPass = true;
        } else {
          this.isPass = false;
        }
      });
    },
    submitData(ruleForm) {
      this.$refs[ruleForm].validate(async(valid) => {
        if (valid) {
          if (this.variants.length > 0) {
            var res = true;
            this.variants.forEach((item) => {
              if (item.variantSku === '' || item.thumbnailUri === undefined) {
                res = false;
              }
            });
            if (!res) {
              this.$message.warning('Please complete the variant information');
              return;
            }
          }
          if (this.dialogType === 'add') {
            materialAdd({
              material: this.material,
              materialVariants: this.variants
            }).then((res) => {
              if (res.code === 200) {
                this.$message.success('success');
                this.dialogFormVisible = false;
                this.init();
              }
            });
          } else if (this.dialogType === 'edit') {
            materialEdit({
              material: this.material,
              materialVariants: this.variants
            }).then((res) => {
              if (res.code === 200) {
                this.$message.success('success');
                this.dialogFormVisible = false;
                this.init();
              }
            });
          }
        } else {
          return false;
        }
      });
    },
    deleteItem(id) {
      this.$confirm(
        'This action will delete the data permanently. Do you want to continue?',
        'Hint',
        {
          confirmButtonText: 'Confirm',
          cancelButtonText: 'Cancel',
          type: 'warning'
        }
      )
        .then(() => {
          const ids = [];
          ids.push(id);
          materialDelete(ids).then((res) => {
            postResult(res, this.$message, this.init);
          });
        })
        .catch(() => {
          this.$message.info('undeleted');
        });
    },
    toProview(url) {
      // 预览图片
      this.proviewUrl = url;
    },
    closeProview() {
      // 关闭预览
      this.proviewUrl = '';
      document.querySelector('body').removeAttribute('style');
    },
    handleSizeChange(val) {
      this.pageSize = val;
      this.currentPage = 1;
      this.init();
    },
    handleCurrentChange(val) {
      this.currentPage = val;
      this.init();
    }
  }
};
</script>
<style lang="scss" scoped>
@import '@/styles/variables.scss';
#groupTree {
  ::v-deep.el-tree--highlight-current {
    .el-tree-node.is-current {
      .el-tree-node__content {
        background-color: rgba(22, 173, 97, 0.5);
      }
    }
  }
}
.groupName {
  width: 182px;
  padding: 4px 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.thumbnailUri {
  >>> .el-form-item__content {
    min-width: 150px;
  }
}
.title {
  background: #f6f6f6;
  height: 32px;
  line-height: 32px;
  padding: 0 20px 0 10px;
  margin-bottom: 15px;
  .el-button {
    float: right;
  }
}
.tip {
  text-align: center;
  font-size: 13px;
  color: #848484;
}
.variantItem {
  display: flex;
  border-top: 1px solid #ddd;
  padding-top: 10px;
  margin-top: -15px;
  .leftArea {
    flex: 1;
  }
  .rightArea {
    width: 50px;
    text-align: center;
  }
}
.dialog-footer {
  padding: 20px 0 10px;
  text-align: right;
}

.content {
  display: flex;
  .groupTree {
    width: 235px;
    margin-right: 15px;
    overflow-y: scroll;
    > div {
      border: 1px solid #ddd;
      background: #fdfdfd;
      padding-bottom: 30px;
      p {
        text-align: center;
        background: #f6f6f6;
        line-height: 36px;
        padding: 0 5px;
        border-bottom: 1px solid #ddd;
      }
      .el-tree {
        padding-top: 10px;
        background: #fdfdfd;
        >>> .el-tree-node {
          height: 30px;
          padding-top: 2px;
          &.is-current {
            .el-tree-node__content {
              background: #409eff;
              color: #fff;
            }
          }
        }
        .custom-tree-node {
          flex: 1;
          display: flex;
          align-items: center;
          justify-content: space-between;
          font-size: 14px;
          padding-right: 8px;
          i.el-icon-edit {
            margin-right: 5px;
            margin-left: 5px;
          }
        }
      }
    }
  }
  .tableBox {
    flex: 1;
    &.open {
      width: calc(100% - #{$sideBarWidth} - 255px);
    }
    .el-table {
      width: 100%;
      ::v-deep.el-table__expanded-cell {
        padding: 10px 50px;
      }
    }
    .productItem {
      display: flex;
      align-items: center;
      background-color: #f5f5f5;
      border-right: 2px solid #fff;
      border-bottom: 2px solid #fff;
      .el-image {
        margin-right: 10px;
      }
      span {
        font-weight: 600;
      }
    }
    #btmPagination {
      width: calc(100% - 54px - 255px);
      z-index: 5;
      &.open {
        width: calc(100% - #{$sideBarWidth} - 255px);
      }
    }
  }
}
</style>
